#import "ChartLyricsLyricsProvider.h"


@implementation ChartLyricsLyricsProvider

@synthesize currentTrack;

- (NSString *) fetchLyricsForSong:(TrackInfo *)track {
	WSMethodInvocationRef ref = [self buildInvocationReference: track];
	
	NSDictionary *result = (NSDictionary *)WSMethodInvocationInvoke(ref);
	if (WSMethodResultIsFault((CFDictionaryRef)result))
		return [NSString string];
	
	return [self getLyrics:result];
}

- (void) beginFetchLyricsForSong:(TrackInfo *)track {
	WSMethodInvocationRef ref = [self buildInvocationReference: track];
	
	self.currentTrack = track;
	context.info = self;
	
	WSMethodInvocationSetCallBack(ref, &callback, &context);
	WSMethodInvocationScheduleWithRunLoop(
		ref, [[NSRunLoop currentRunLoop] getCFRunLoop], (CFStringRef)NSDefaultRunLoopMode
	);
}

- (WSMethodInvocationRef) createInvocationReference {
	NSURL *url = [NSURL URLWithString:@"http://api.chartlyrics.com/apiv1.asmx"];
	NSString *methodName = @"SearchLyricDirect";
	
	return WSMethodInvocationCreate(
		(CFURLRef)url, 
		(CFStringRef)methodName, 
		kWSSOAP2001Protocol
	);
}

- (void) setInvocationReferenceParameters:(WSMethodInvocationRef)ref song:(NSString *)song artist:(NSString *)artist  {
	NSDictionary *params = [NSDictionary 
		dictionaryWithObjects: [NSArray arrayWithObjects: artist, song, nil] 
	    forKeys: [NSArray arrayWithObjects: @"artist", @"song", nil]
	];
	
	NSArray *paramOrder = [NSArray arrayWithObjects: @"artist", @"song", nil];
	
	WSMethodInvocationSetParameters(
		ref, (CFDictionaryRef)params, (CFArrayRef)paramOrder
	);

}

- (void) setInvocationReferenceProperties:(WSMethodInvocationRef)ref  {
    NSString *namespace = @"http://api.chartlyrics.com/";
    NSDictionary *reqHeaders = [NSDictionary 
		dictionaryWithObject:@"http://api.chartlyrics.com/SearchLyricDirect" 
		forKey:@"SOAPAction"
	];
	
    WSMethodInvocationSetProperty(ref, kWSSOAPMethodNamespaceURI, (CFStringRef)namespace);
    WSMethodInvocationSetProperty(ref, kWSHTTPExtraHeaders, (CFDictionaryRef)reqHeaders);
    WSMethodInvocationSetProperty(ref, kWSHTTPFollowsRedirects, kCFBooleanTrue);
	
	// set debug props
    WSMethodInvocationSetProperty(ref, kWSDebugIncomingBody, kCFBooleanTrue);
    WSMethodInvocationSetProperty(ref, kWSDebugIncomingHeaders, kCFBooleanTrue);
    WSMethodInvocationSetProperty(ref, kWSDebugOutgoingBody, kCFBooleanTrue);
    WSMethodInvocationSetProperty(ref, kWSDebugOutgoingHeaders, kCFBooleanTrue);
}

- (WSMethodInvocationRef) buildInvocationReference:(TrackInfo *)track  {
	WSMethodInvocationRef ref = [self createInvocationReference];
	
	[self setInvocationReferenceParameters:ref song:track.name artist:track.artist];
	[self setInvocationReferenceProperties:ref];
  return ref;
}

- (NSString *) getLyrics:(NSDictionary *)result {
	NSDictionary *response = [result objectForKey:(id)kWSMethodInvocationResult];
	
	return [[response objectForKey:@"SearchLyricDirectResult"] objectForKey:@"Lyric"];
}

- (void) methodCallback:(NSDictionary *)result {
	if (WSMethodResultIsFault((CFDictionaryRef)result))
		return;
		
	NSNotification *notification = [NSNotification 
		notificationWithName:@"lyricsFetched" 
		object:self 
		userInfo:[
			NSDictionary 
				  dictionaryWithObjects: [NSArray arrayWithObjects:[self getLyrics:result], self.currentTrack, nil] 
				  forKeys:[NSArray arrayWithObjects:@"Lyrics", @"Track", nil]
		]
	];
	
	[[NSNotificationCenter defaultCenter] postNotification:notification]; 
}

- (void) dealloc {
	context.info = NULL;
	self.currentTrack = nil;
	
	[super dealloc];
}

void callback(WSMethodInvocationRef invocation, void *info, CFDictionaryRef outRef) {
	[(ChartLyricsLyricsProvider *)info methodCallback:(NSDictionary *)outRef];
}

@end
